from fastapi import FastAPI, Request
from ipex_llm.transformers import AutoModel
from transformers import AutoTokenizer
import uvicorn, json, datetime
import torch
import os

DEVICE = "cpu"  # Change to "cuda" if you want to enable GPU support

app = FastAPI()


def torch_gc():
    if torch.cuda.is_available():
        torch.cuda.empty_cache()


@app.post("/")
async def create_item(request: Request):
    global model, tokenizer
    json_post_raw = await request.json()
    json_post = json.dumps(json_post_raw)
    json_post_list = json.loads(json_post)
    prompt = json_post_list.get('prompt')
    history = json_post_list.get('history')
    max_length = json_post_list.get('max_length')
    top_p = json_post_list.get('top_p')
    temperature = json_post_list.get('temperature')
    with torch.no_grad():  # Ensure no gradients are computed
        response, history = model.chat(tokenizer,
                                       prompt,
                                       history=history,
                                       max_length=max_length if max_length else 2048,
                                       top_p=top_p if top_p else 0.7,
                                       temperature=temperature if temperature else 0.95)
    now = datetime.datetime.now()
    time = now.strftime("%Y-%m-%d %H:%M:%S")
    answer = {
        "response": response,
        "history": history,
        "status": 200,
        "time": time
    }
    log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'
    print(log)
    torch_gc()
    return answer


if __name__ == '__main__':
    MODEL_PATH = os.environ.get('MODEL_PATH', r'D:\AtomGit\model\chatglm3-ipex-int4')
    TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", r'D:\AtomGit\model\chatglm3-6b')

    # ipex-gpu加速
    model = AutoModel.load_low_bit(MODEL_PATH, trust_remote_code=True)
    tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH, trust_remote_code=True)
    model.eval()
    model.to('xpu')
    
    # 格式化提示
    CHATGLM_V3_INIT_PROMPT_TEMPLATE = "这是Warm-up过程，无需做出回答\n"

    prompt = CHATGLM_V3_INIT_PROMPT_TEMPLATE

    # 编码提示
    input_ids = tokenizer.encode(prompt, return_tensors="pt")

    input_ids = input_ids.to('xpu')

    output = model.generate(input_ids,
                        do_sample=False,
                        max_new_tokens=32) # warm-up
    
    history2 = []
    with torch.no_grad():  # Ensure no gradients are computed
        response, history = model.chat(tokenizer,
                                        prompt,
                                        history=history2,
                                        max_length=2048,
                                        top_p=0.7,
                                        temperature=0.95)
    torch_gc()

    print("----------- 聊天模型成功加载 -----------")
    
    uvicorn.run(app, host='0.0.0.0', port=8000, workers=1)
